package com.hqd.ch03.v20.aop.framework;

import lombok.AllArgsConstructor;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.List;

public class ProxyFactory extends AdvisedSupport {

    public ProxyFactory(Object target) {
        super(target);
    }

    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(getTargetClass());
        /**
         * 添加默认拦截器，执行增强
         */
        enhancer.setCallbacks(new Callback[]{new DynamicAdvisedInterceptor(this)});
        enhancer.setInterfaces(getInterfaces().toArray(new Class[]{}));
        return enhancer.create();
    }

    @AllArgsConstructor
    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
        private AdvisedSupport advised;


        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Class<?> targetClass = this.advised.getTargetClass();
            Object target = this.advised.getTarget();
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            ReflectiveMethodInvocation rmi = new ReflectiveMethodInvocation(target, proxy,
                    method, args, chain.toArray(new Object[0]));
            return rmi.proceed();
        }
    }
}
